home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 436_01 / intempl.c < prev    next >
Text File  |  1994-10-07  |  13KB  |  513 lines

  1. /*************************************************************************
  2.     Source file:  INTEMPL.C
  3.  
  4.     INCON template input handler.
  5.  
  6.     Compiler:  Borland Turbo C 2.01
  7.  
  8.     INCON source files and the object and library files created from
  9.     them are:
  10.         Copyright (c) 1993-94, Richard Zigler.
  11.     You may freely distribute unmodified source, object, and library
  12.     files, and incorporate them into your own non-commercial software,
  13.     provided that this paragraph and the program name and copyright
  14.     strings defined in INCON.C are included in all copies.
  15. *************************************************************************/
  16.  
  17. #include <conio.h>
  18. #include <ctype.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "indefs.h"                            /* globals and definitions            */
  22. #include "incon.h"                            /* state definitions                    */
  23. #include "indecl.h"                            /* public utility routines            */
  24.  
  25. /**** Local Data ****/
  26.  
  27. typedef enum
  28.             {
  29.             T_INIT                        ,        /* initialize template string        */
  30.             F_CHAR                        ,        /* find first input slot            */
  31.             L_CHAR                        ,        /* find last input slot                */
  32.             N_CHAR                        ,        /* find next input slot                */
  33.             P_CHAR                        ,        /* find previous input slot        */
  34.             N_WORD                        ,        /* find next input word                */
  35.             P_WORD                        ,        /* find previous input word        */
  36.             S_WORD                        ,        /* find start of current word        */
  37.             E_WORD                        ,        /* find end of current word        */
  38.             T_WIPE                        ,        /* clear template                        */
  39.             T_STRIP                        ,        /* strip delimiters                    */
  40.             }                TEMPL_OP        ;        /* template opcodes                    */
  41.  
  42. typedef enum
  43.             {
  44.             MIX_DELIM                    ,        /* template delimiter                */
  45.             MIX_ALPHA                    ,        /* alpha input slot                    */
  46.             MIX_UPPER                    ,        /* uppercase input slot                */
  47.             MIX_INTGR                    ,        /* integer input slot                */
  48.             }                TEMPL_CHAR    ;        /* template characters                */
  49.  
  50. /**** Local Routines ****/
  51.  
  52. static int near pascal    TemplateFix
  53.                 (
  54.                 TEMPL_OP        Op,                /* operation requested                */
  55.                 int            Pos                /* position in source string        */
  56.                 )                ;
  57.  
  58. /***********************************************************************/
  59.  
  60. int pascal hTemplateField( STATES State, register int Pos )
  61. {
  62. register int        work;                        /* integer-size working storage    */
  63.             BFLAG        match;                    /* character match flag                */
  64.  
  65. switch( State )
  66.     {
  67.     case stError:
  68.         break;
  69.  
  70.     case stQuit:                                /* [Enter] -- end input                */
  71.  
  72.         if ( strchr( OutStr, Fill ) )
  73.             Chr = -1;
  74.         else if ( !(Chr == K_PLUS || Chr == K_MINUS) )
  75.             Chr = 0;
  76.         if ( Flags.Strip )
  77.             TemplateFix( T_STRIP, 0 );
  78.         More = NO;
  79.         break;
  80.  
  81.     case stInit:                                /* field initialization                */
  82.  
  83.         if ( DisplayStr != NULL )
  84.             Pos = TemplateFix( T_INIT, 0 );
  85.         break;
  86.  
  87.     case stFieldClear:                        /* [Esc] -- clear field or exit    */
  88.  
  89.         if ( EscSet )
  90.             More = NO;
  91.         else
  92.             {
  93.             Pos = TemplateFix( T_WIPE, 0 );
  94.             ++Update;
  95.             }
  96.         break;
  97.  
  98.     case stDeleteCharLeft:                    /* [Backspace] -- delete left        */
  99.  
  100.         if ( !(Pos == TemplateFix( F_CHAR, 0  )) )
  101.             {
  102.  
  103.             /* if at last slot in template and not already vacant                */
  104.  
  105.             if (OutStr[Pos] != (char)Fill && Pos == TemplateFix(L_CHAR, 0))
  106.                 OutStr[Pos] = Fill;
  107.  
  108.             /* else if not at word boundary                                            */
  109.  
  110.             else if ( DisplayStr[Pos - 1] )
  111.                 {
  112.                 work = TemplateFix( E_WORD, Pos );
  113.                 --Pos;
  114.                 memcpy( OutStr + Pos, OutStr + Pos + 1, work - Pos );
  115.                 OutStr[work] = Fill;
  116.                 }
  117.  
  118.             /* else move to last slot in previous word and delete that        */
  119.  
  120.             else
  121.                 {
  122.                 Pos = TemplateFix( P_CHAR, Pos );
  123.                 OutStr[Pos] = Fill;
  124.                 }
  125.  
  126.             /* if hidden input, fix display here and flag move only            */
  127.  
  128.             if ( Flags.Hide )
  129.                 {
  130.                 PutCursor( Row, Col + Pos );
  131.                 putch( Fill );
  132.                 --Move;
  133.                 }
  134.             else
  135.                 ++Update;
  136.             }
  137.         break;
  138.  
  139.     case stMoveToStart:                        /* [Home] -- start of field        */
  140.  
  141.         work = Pos;
  142.         Pos = TemplateFix( F_CHAR, 0 );
  143.         goto __MinusMove;
  144.  
  145.     case stMoveCharLeft:                        /* [Left Arrow] -- move char lt    */
  146.  
  147.         work = Pos;
  148.         Pos = TemplateFix( P_CHAR, Pos );
  149.         goto __MinusMove;
  150.  
  151.     case stMoveCharRight:                    /* [Right Arrow] -- move char rt    */
  152.  
  153.         work = Pos;
  154.         Pos = TemplateFix( N_CHAR, Pos );
  155.         goto __PlusMove;
  156.  
  157.     case stMoveToEnd:                            /* [End] -- end of field            */
  158.  
  159.         work = Pos;
  160.         Pos = TemplateFix( L_CHAR, 0 );
  161.         goto __PlusMove;
  162.  
  163.     case stMoveWordLeft:                        /* [Ctrl Left] -- move word lt    */
  164.  
  165.         work = Pos;
  166.         Pos = TemplateFix( P_WORD, Pos );
  167.  
  168. __MinusMove:
  169. ;
  170.         if ( work != Pos )
  171.             --Move;
  172.         break;
  173.  
  174.     case stMoveWordRight:                    /* [Ctrl Right] -- move word rt    */
  175.  
  176.         work = Pos;
  177.         Pos = TemplateFix( N_WORD, Pos );
  178.  
  179. __PlusMove:
  180. ;
  181.         if ( work != Pos )
  182.             ++Move;
  183.         break;
  184.  
  185.     case stDeleteWordLeft:                    /* [Ctrl L] -- delete word left    */
  186.  
  187.         if ( !Flags.Hide && !(Pos == TemplateFix( F_CHAR, 0  )) )
  188.             {
  189.             if ( DisplayStr[Pos - 1] )        /* if within word                        */
  190.                 {
  191.                 work    = Pos;
  192.                 Pos    = TemplateFix( S_WORD, Pos );
  193.                 }
  194.             else                                    /* at word boundary                    */
  195.                 {
  196.                 Pos    = TemplateFix( P_WORD, Pos );
  197.                 work    = TemplateFix( E_WORD, Pos );
  198.                 }
  199.             memset( OutStr + Pos, Fill, work - Pos + 1 );
  200.             ++Update;
  201.             }
  202.         break;
  203.  
  204.     case stDeleteWordRight:                    /* [Ctrl R] -- delete word right    */
  205.  
  206.         if ( !Flags.Hide && !(Pos == TemplateFix( L_CHAR, 0  )) )
  207.             {
  208.             if ( !DisplayStr[Pos + 1] )                 /* if at word boundary    */
  209.                 Pos = TemplateFix( N_WORD, Pos );     /*  move to next word    */
  210.             work = TemplateFix( E_WORD, Pos );
  211.             memset( OutStr + Pos, Fill, work - Pos + 1 );
  212.             ++Update;
  213.             }
  214.         break;
  215.  
  216.     case stDeleteToEnd:                        /* [Ctrl End] -- clear to end        */
  217.  
  218.         if ( !(Pos == TemplateFix( L_CHAR, 0  )) )
  219.             {
  220.             TemplateFix( T_WIPE, Pos );
  221.             ++Update;
  222.             }
  223.         break;
  224.  
  225.     case stDeleteToStart:                    /* [Ctrl Home] -- clear to start    */
  226.  
  227.         if ( !(Pos == TemplateFix( F_CHAR, 0  )) )
  228.             {
  229.             Pos = TemplateFix( -(T_WIPE), Pos );
  230.             ++Update;
  231.             }
  232.         break;
  233.  
  234.     case stDeleteAtCursor:                    /* [Del] -- delete at cursor        */
  235.  
  236.         work = TemplateFix( E_WORD, Pos );
  237.         if ( work != Pos )
  238.             memcpy( OutStr + Pos, OutStr + Pos + 1, work - Pos );
  239.         OutStr[work] = Fill;
  240.         ++Update;
  241.         break;
  242.  
  243.     case stExitPlus:                            /* [Keypad +] -- special exit        */
  244.     case stExitMinus:                            /* [Keypad -] -- special exit        */
  245.  
  246.         /****
  247.             Treat these keys as exit requests in integer templates.
  248.             In alpha templates, convert to '+' or '-' and fall through
  249.             to the match state.
  250.         ****/
  251.  
  252.         if ( Flags.Type == INTGR )
  253.             {
  254.             hTemplateField( stQuit, 0 );
  255.             break;
  256.             }
  257.         else
  258.             Chr = (State == stExitPlus) ? '+' : '-' ;
  259.  
  260.     case stCharMatch:                            /* see if entry matches field        */
  261.  
  262.         match    = NO;
  263.         work    = DisplayStr[Pos];
  264.         if ( work )
  265.             {
  266.             switch( Flags.Type )
  267.                 {
  268.                 case UPPER:
  269. __Upper:
  270. ;
  271.                     Chr = toupper( Chr );    /* convert and fall through        */
  272.  
  273.                 case ALPHA:
  274. __Alpha:
  275. ;
  276.                     match =    Flags.Type == MIXED    ?        /* if mixed,            */
  277.                                  isalpha( Chr )        :        /* match alpha only    */
  278.                                 !iscntrl( Chr )        ;        /* else match all        */
  279.                     break;
  280.  
  281.                 case INTGR:
  282. __Integer:
  283. ;
  284.                     match = isdigit( Chr );
  285.                     break;
  286.  
  287.                 case MIXED:
  288.  
  289.                     if ( work == MIX_ALPHA )
  290.                         goto __Alpha;
  291.                     else if ( work == MIX_UPPER )
  292.                         goto __Upper;
  293.                     else
  294.                         goto __Integer;
  295.                 }                                    /* switch (Type)                        */
  296.             }                                        /* if (work)                            */
  297.         if ( match )
  298.             {
  299.             if ( InBegin )
  300.                 {
  301.                 hTemplateField( stFieldClear, 0 );
  302.                 PutCursor( Row, Col );
  303.                 cputs( OutStr );
  304.                 PutCursor( Row, Col + Pos );
  305.                 }
  306.          OutStr[Pos++] = Chr;
  307.             if ( Flags.Hide )
  308.                 putch( ' ' );
  309.             if ( !DisplayStr[Pos] )
  310.                 Pos = TemplateFix( N_CHAR, Pos );
  311.             ++Update;
  312.             }
  313.         else
  314.             State = stError;
  315.         break;
  316.     }                                                /* switch (State)                        */
  317. return( Pos );
  318. }                                                    /**** hTemplateField()            ****/
  319.  
  320. /*************************************************************************
  321.     TemplateFix()
  322.  
  323.     hTemplateField() calls on this routine to initialize template fields
  324.     and manage the cursor within them.  During initialization an image
  325.     of the input string passed from the caller is built in DisplayStr,
  326.     which is otherwise unused when the Template flag is set.  Each
  327.     "template delimiter" in the input st